# This is a sample Python script.
import os
import logging
import zlib
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

"""
python实现的校验和公式如下
row_line : param str 为每行记录,最后一个字节为校验和,
          计算记录的前面部分和校验和是否相等
"""

class HexHandle():
    # 数据类型
    data_type_dict = {
        0: '记录数据',
        1: '文件结束',
        2: '扩展段地址的记录',  # <<4
        3: "开始段地址记录",
        4: "扩展线性地址的记录",  # <<16
        5: "开始线性地址记录",  # 对于嵌入式HEX无用
    }

    def __init__(self, path):
        # path hex文件的路径
        self.path = path

    def get_filecrc(self):
        res = 0
        for line in open(self.path,'rb'):
            res = zlib.crc32(line,res)
        return "%X"%(res & 0xFFFFFFFF)

    def get_hex_data(self):
        text_list = []
        if os.path.exists(self.path) is False:
            return text_list

        with open(self.path, 'rb') as fp:
            _text_list = fp.readlines()
            text_list = [str(_, 'utf-8').replace("\r\n", "").replace(":", "") for index, _ in enumerate(_text_list) if
                         _]
        # print(text_list)
        return text_list

    def func_parse_hex(self,row_line):
        # data_list = self.get_hex_data()
        # row_line = data_list[0]
        # 数据长度
        data_length = int(row_line[:2], 16)
        # 数据类型
        type_int = int(row_line[7:8], 16)
        data_type = self.data_type_dict.get(type_int)
        _index = row_line[2:6]
        # 有效数据
        data = row_line[-2 - data_length * 2:-2]
        jy_text = row_line[-2:]

        check_num = hex(0x100 - (sum([int(row_line[i:i + 2], 16) for i in range(0, len(row_line[:-2]), 2)])) & 0xFF)
        is_pass = check_num == hex(int(jy_text, 16))

        _pars_res = {
            "数据类型": data_type,
            "数据长度": f"{data_length}",
            "偏移地址": _index,
            # "源数据": row_line,
            "有效数据": data,
            "校验和": f"{jy_text}<->{check_num}",
            "实际计算地址": "",
            "校验结果": is_pass,
        }
        # print(_pars_res)
        return _pars_res

    def get_res(self):
        """
        物理地址为：基地址 X 16D（相当于在基地址后面添一个0）+ 偏移地址
        当一个扩展线性地址记录被读取，存储于数据域的扩展线性地址被保存，它被应用于从 Intel HEX 文件读取来的随后的记录
        线性地址保持有效，直到它被另外一个扩展地址记录所改变
        通过把记录当中的地址域与被移位的来自扩展线性地址记录的地址数据相加获得数据记录的绝对存储器地址
        :return: dict
        """
        data_list = self.get_hex_data()
        data = ""
        start_index = ""
        start_index1, start_index2 = "", ""
        is_pass = True
        data_flag = 0

        for _index, row_line in enumerate(data_list):
            row_dict = self.func_parse_hex(row_line)
            if row_dict["数据类型"] == "记录数据":
                data += row_dict["有效数据"]
            elif row_dict["数据类型"] == "扩展线性地址的记录" and _index == 0:
                start_index1 = f'{row_dict["有效数据"]}'
                print("start_index1:",start_index1)
                print("type of start_index1:",type(start_index1))
                data_flag = 1
            elif row_dict["数据类型"] == "记录数据" and _index == 0:
                start_index1 = None
                data_flag = 0

            _is_pass = row_dict["校验结果"]
            if _is_pass is False:
                is_pass = False
            if data_flag == 1:
                if _index == 1:
                    start_index2 = f'{row_dict["偏移地址"]}'
                    print("start_index2:",start_index2)
            elif data_flag == 0:
                if _index == 0:
                    start_index2 = f'{row_dict["偏移地址"]}'
                    print("start_index2:",start_index2)
        # 起始地址为, 第一行的有效数据和 第二行的偏移地址相加
        if start_index1 and start_index2:
            logger.info(f"start_index {start_index1} + {start_index2}")
            # start_index = hex(int(start_index1, 16) + int(start_index2, 16))[2:]
            start_index_str = start_index1+start_index2
            start_index = int(start_index_str, 16)
            print("start_index:",start_index)
        else:
            logger.info(f"start_index {start_index2}")
            # start_index = hex(int(start_index1, 16) + int(start_index2, 16))[2:]
            start_index_str = start_index2
            start_index = int(start_index_str, 16)
            print("start_index:",start_index)
        # 有效数据长度
        data_length = int(len(data) / 2)
        logger.info(f"data_length={data_length}  start_index={start_index} 校验结果{is_pass}")
        data_dict = {
            "data": data,
            "data_length": data_length, #hex(data_length)[2:].rjust(8, "0"),  # 4个字节 不足4个 用0补齐
            "start_index": start_index,#start_index.rjust(8, "0"),  # 4个字节  不足4个 用0补齐
            "is_pass": is_pass,
        }
        return data_dict
